from . import passport_blue
from flask import request, jsonify, current_app, make_response, session, redirect, g
from info.utils.captcha.captcha import captcha
from info.utils.response_code import RET
from info import constants, db
from info.models import *
import re, random
from info.libs.yuntongxun import sms
from info import redis_store


# 临时定义一个数据库
# from redis import StrictRedis
#
# redis_store = StrictRedis(host="127.0.0.1", port=6379)


@passport_blue.route('/image_code')
def generate_image_code():
    """
    步骤：1 获取浏览器传入的数据,参数的名称为image_code_id
    2 判断数据的是否为空值
    3 接受传入的参数，并且存储相应的值(图片名称)
    4 通过captcha模块生成相应的图片, 和验证码，存储
    临时的数据（图片的名称和验证码至redis数据库，设置相应的有效时间)
    5 将图片和图片的名称返回值页面，由页面接受相应的数据
    :return:

    """
    # 1 获取浏览器的数据
    image_code_id = request.args.get("image_code_id")
    # print(image_code_id)
    # 2 判断数据是否为空值，如果为空，返回相应的错误信息
    if not image_code_id:
        return jsonify(errno=RET.PARAMERR, errmsg="缺少参数")
    # 3 生成相应的数据
    name, text, image = captcha.generate_captcha()

    # 4  将数据存入相应的数据库
    try:
        redis_store.setex("ImageCode_" + image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
    except Exception as e:
        # 记录错误的信息
        current_app.logging.error(e)
        return jsonify(errno=RET.DBERR, errsmg="保存图片失败")
    else:
        # 如果保存成功，返回相应的数据给浏览器
        response = make_response(image)
        response.headers["Content-Type"] = "image/jpg"
        return response


@passport_blue.route('/sms_code', methods=["POST"])
def send_sms_code():
    # 1 获取参数 name="mobile" name="code_pwd"  var imageCodeId = ""
    mobile = request.json.get("mobile")
    image_code = request.json.get("image_code")
    image_code_id = request.json.get("image_code_id")

    # 2检查参数的完整性
    if not all([mobile, image_code, image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    # 3检查手机格式的正确性
    if not re.match(r'1[3456789]\d{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机号码格式不正确")

    # 4 获取本地数据库的图片验证码
    try:
        real_image_code = redis_store.get("ImageCode_" + image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="验证码失效")
    else:
        # print(real_image_code, image_code)
        if real_image_code.lower() != image_code.lower():
            return jsonify(errno=RET.PARAMERR, errmsg="验证码不一致")
        else:
            # 如果匹配成功，需要删除图片验证码，因为图片验证码只能比较一次，本质是只能读取redis数据库一次
            try:
                redis_store.delete("ImageCode_" + image_code_id)
            except Exception as e:
                current_app.logger.error(e)

    # 5 生成随机数据,并将数据存储在redis数据库中
    sms_code = '%06d' % random.randint(0, 999999)
    try:
        redis_store.setex("SMSCode_" + mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="保存随机短信失败")

    # 6 发送数据至云通信（修改sms.py文件中的SID、token、appid）
    try:
        ccp = sms.CCP()
        result = ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES / 60], 1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg="发送数据失败")

    # 7 判断结果
    if result == 0:
        return jsonify(errno=RET.OK, errmsg="发送成功")
    else:
        return jsonify(errno=RET.THIRDERR, errmsg="发送失败")


@passport_blue.route('/register', methods=["POST"])
def register():
    # 1 获取相应的数据
    mobile = request.json.get("mobile")
    sms_code = request.json.get("smscode")
    password = request.json.get("password")
    # 2 判断数据是不是完整的
    if not all([mobile, sms_code, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="输入的数据不完整")
    # 3 如果mobile smscode password有数据，首先验证mobile
    # 是不是满座1相应的规则以及数据库中是否已经存在相应的数据
    # not re.match(r'1[3456789]\d{9}$', mobile)

    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        return jsonify(errno=RET.DBERR, errmsg="数据库异常")
    else:
        if user:
            return jsonify(errno=RET.DATAEXIST, errmsg="手机号码已经注册")

    # 4 验证sms_code是不是正确的
    try:
        real_sms_code = redis_store.get("SMSCode_" + mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="手机验证码获取失败")
    else:
        if not real_sms_code:
            return jsonify(errno=RET.NODATA, errmsg="手机验证码已经过期")
        elif real_sms_code != str(sms_code):
            return jsonify(errno=RET.DATAERR, errmsg="手机验证码不正确")

    # 5 验证密码是不是满足要求(前段已经完成相应的验证，此时暂不考虑验证数据)
    # 6 保存数据至sql数据库
    # new_user = User(nick_name=mobile, mobile=mobile, password_hash=password)
    new_user = User()
    new_user.nick_name = mobile
    new_user.mobile = mobile
    new_user.password = password
    try:
        db.session.add(new_user)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg="保存数据错误")
    else:
        return jsonify(errno=RET.OK, errmsg="注册成功")


@passport_blue.route('/login', methods=["POST"])
def login():
    # 登陆的基本流程
    # 1 前段发送用户名和密码，后端接受，并且验证数据的完整性
    # 2 检查用户是否存在以及用户名的格式是不是正确的（用户已经存在 提示注册）
    # 3 查询数据库，检验密码是不是正确的（提示密码错）
    # 4 如果所有的数据都是正确的，即登陆成功
    mobile = request.json.get("mobile")
    password = request.json.get("password")
    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="数据不完整")

    if not re.match(r'1[345678]\d{9}$', mobile):
        return jsonify(errno=RET.DATAERR, errmsg="手机格式错误")

    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库错误")
    # if not user:
    #     return jsonify(errno=RET.NODATA, errmsg="用户不存在")
    # if not user.check_password(password):
    #     return jsonify(errno=RET.DATAERR, errmsg="密码错误")
    if (not user) or (not user.check_password(password)):
        return jsonify(errno=RET.DATAERR, errmsg="用户名或密码错误")
        # 登陆成功后，需要1 将用户名最后登陆的时间存在sql数据库中
        # 2 将id nick_name mobile保存至session中
        # 3 跳转至主界面，显示用户的头像 用户名
    user.last_login = datetime.now()
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库错误")

    session["user_id"] = user.id
    session["nick_name"] = user.nick_name
    session["mobile"] = user.mobile

    return jsonify(errno=RET.OK, errmsg="OK")


@passport_blue.route("/logout")
def logout():
    """
    清除session中的对应登录之后保存的信息
    :return:
    """
    session.pop('user_id', None)
    session.pop('nick_name', None)
    session.pop('mobile', None)
    session.pop('is_admin', None)

    # 返回结果
    # return jsonify(errno=RET.OK, errmsg="OK")
    return redirect("/")




